package com.strato.rule.core.v1_0_0.execution;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Map;

import com.strato.rule.core.v1_0_0.annotation.RuleFact;
import com.strato.rule.core.v1_0_0.annotation.RuleGlobal;
import com.strato.rule.core.v1_0_0.annotation.RuleParam;

public class RuleItem {
	
	private String ruleId;
	
	public String getRuleId() {
		return ruleId;
	}

	public void setRuleId(String ruleId) {
		this.ruleId = ruleId;
	}
	
	private Map<String,Object> params;

	public Map<String, Object> getParams() {
		return params;
	}

	public void setParams(Map<String, Object> params) {
		this.params = params;
	}

	protected void execute(Session session) throws RuleExecutionException{
		Rule rule=session.getRuleEngine().getRule(ruleId);
		Method method = rule.getMethod();
		Object owner = rule.getOwner();
		Parameter[] params = method.getParameters();
		Object[] args=new Object[params.length];
		for(int i=0;i<params.length;i++){
			Parameter param = params[i];
			RuleFact rf = param.getAnnotation(RuleFact.class);
			RuleGlobal rg=param.getAnnotation(RuleGlobal.class);
			RuleParam rp=param.getAnnotation(RuleParam.class);
			String name = param.getName();
			Object arg=null;
			if(rf!=null){
				arg=session.getFact(name);
			}else if(rg!=null){
				arg=session.getGlobal(name);
			}else if(rp!=null){
				arg=this.params.get(name); 
			}
			args[i]=arg;
		}
		try {
			method.invoke(owner, args);
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
			throw new RuleExecutionException(e);
		}
	}

}
